package com.cq.xjms.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.extremecomponents.table.limit.Limit;

import com.cq.xjms.model.BaseEntity;
import com.cq.xjms.service.BaseManager;

/**
 * Service 鍩虹绫�
 */
public class  BaseManagerImpl<T extends BaseEntity> implements BaseManager<T>{

	@PersistenceContext
	protected EntityManager em;

	public void setEntityManager(EntityManager em) {
		this.em = em;
	}

	public Query query(String hql) {
		return em.createQuery(hql);
	}

	public Query namedQuery(String name) {
		return em.createNamedQuery(name);
	}

	public Query nativeQuery(String sql) {
		return em.createNativeQuery(sql);
	}

	@SuppressWarnings("unchecked")
	public T load(Class clazz, Long id) {
		return (T)em.find(clazz, id);
	}

	public void save(T entity) {
		try{
		em.persist(entity);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	public void update(T entity) {
		em.merge(entity);
	}

	public void saveOrUpdate(T entity) {
		if (entity.getId() == null)
			em.persist(entity);
		else
			em.merge(entity);
	}

	@SuppressWarnings("unchecked")
	public void remove(Class clazz, Long id) {
		em.remove(load(clazz, id));
	}

	public int count(String queryName) {
		return count(queryName, null);
	}
	public int count(String queryName, Map<String, Object> parameters) {
		Query query = namedQuery(queryName);
		if (parameters != null)
			for (Map.Entry<String, Object> entry : parameters.entrySet())
				query.setParameter(entry.getKey(), entry.getValue());
		Object result = query.getSingleResult();
		return result == null ? 0
				: result instanceof Integer ? ((Integer) result).intValue()
						: ((Long) result).intValue();
	}
	
	
	@SuppressWarnings("unchecked")
	public List<T> find(String queryName) {
		return find(queryName, null, null);
	}

	@SuppressWarnings("unchecked")
	public List<T> find(String queryName, Limit limit) {
		return find(queryName, null, limit);
	}

	@SuppressWarnings("unchecked")
	public List<T> find(String queryName, Map<String, Object> parameters) {
		List list = null;
		try{
			list = find(queryName, parameters, null);
		}catch(Exception e){
			e.printStackTrace();
		}
		return list;
	}

	@SuppressWarnings("unchecked")
	public List<T> find(String queryName, Map<String, Object> parameters,
			Limit limit) {
		Query query = namedQuery(queryName);
		if (parameters != null) {
			for (Map.Entry<String, Object> entry : parameters.entrySet())
				query.setParameter(entry.getKey(), entry.getValue());
		}
		if (limit != null) {
			query.setFirstResult((limit.getPage() - 1)
					* limit.getCurrentRowsDisplayed());
			query.setMaxResults(limit.getCurrentRowsDisplayed());
		}
		return query.getResultList();
	}

	public int countByHQL(String queryHQL, Map<String, Object> parameters) {
		Query query = query(queryHQL);
		if (parameters != null)
			for (Map.Entry<String, Object> entry : parameters.entrySet())
				query.setParameter(entry.getKey(), entry.getValue());
		Object result = query.getSingleResult();
		return result == null ? 0
				: result instanceof Integer ? ((Integer) result).intValue()
						: ((Long) result).intValue();
	}

	@SuppressWarnings("unchecked")
	public List<T> findByHQL(String queryHQL, Map<String, Object> parameters,
			Limit limit) {
		Query query = query(queryHQL);
		if (parameters != null) {
			for (Map.Entry<String, Object> entry : parameters.entrySet())
				query.setParameter(entry.getKey(), entry.getValue());
		}
		if (limit != null) {
			query.setFirstResult((limit.getPage() - 1)
					* limit.getCurrentRowsDisplayed());
			query.setMaxResults(limit.getCurrentRowsDisplayed());
		}
		return query.getResultList();
	}
	
	public void update(String queryName, Map<String, Object> parameters) {
		Query query = namedQuery(queryName);
		if (parameters != null)
			for (Map.Entry<String, Object> entry : parameters.entrySet())
				query.setParameter(entry.getKey(), entry.getValue());
		query.executeUpdate();
	}

}
